package com.kob.matchingsystem.service.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

@Component //必须在springboot中扫描到的类才能使用@Autowired注解
public class MatchingPool extends Thread {
    private static List<Player> players = new ArrayList<>();
    private ReentrantLock lock = new ReentrantLock();

    private static RestTemplate restTemplate;

    private final static String startGameUrl = "http://127.0.0.1:3000/pk/start/game/";

    @Autowired
    public  void setRestTemplate(RestTemplate restTemplate) {
        MatchingPool.restTemplate = restTemplate;
    }

    public void addPlayer(Integer userId, Integer rating,Integer botId ){
        lock.lock();
        try {
            players.add(new Player(userId,rating,botId,0));
        }finally {
            lock.unlock();
        }
    }
    public void removePlayer (Integer userId){
        lock.lock();
        try{
            for (int i = 0; i < players.size(); i++) {
                if(players.get(i).getUserId().equals(userId)){
                    players.remove(i);
                    i--; //注意指针回退；这样i++之后重新判断下一个位置
                }
            }
        }finally {
            lock.unlock();
        }
    }

    private void matchPlayers(){ //尝试匹配所有玩家
        System.out.println("match players" + players.toString());
        boolean[] used = new boolean[players.size()];//bool组存储那些玩家已经有结果了
        //优先匹配等待时间最长的玩家
        for (int i = 0; i < players.size(); i++) {
            if(used[i]) continue;
            for (int j = i+1; j < players.size() ; j++) {
                if(used[j]) continue;
                Player a = players.get(i);
                Player b = players.get(j);
                if(checkMatched(a,b)){
                    used[i] = used[j] = true;
                    sendResult(a,b);
                    break;
                }
            }
        }
        //更新players 删除已经匹配过的玩家
        for (int i = 0; i < players.size(); i++) {
            if(used[i]){
                players.remove(i);
                i--;
            }
        }

    }

    //辅助函数
    //遍历玩家列表，让每个玩家等待时间+1
    private void increaseWaitingTime(){
        for(Player player :players){
            player.setWaitingTime(player.getWaitingTime()+1);
        }
    }
    //检测两个玩家是否在当前的等待时间下是否可以匹配分差
    private boolean checkMatched(Player a, Player b ){//判断两名玩家是否匹配
        int ratingDelta = Math.abs(a.getRating() - b.getRating());
        //对a来说：ratingDelta <= a.getWaitingTime()*10;
        //对b来说：ratingDelta <= b.getWaitingTime()*10;
        int waitingTime = Math.min(a.getWaitingTime(),b.getWaitingTime());
        return ratingDelta <= waitingTime*10;
    }
    //发送结果
    private void sendResult(Player a, Player b ){ //若a和b 匹配，则作为参数返回到backend
        System.out.println("send Result " + a + " " + b);
        MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
        data.add("a_id",a.getUserId().toString());
        data.add("a_bot_id",a.getBotId().toString());
        data.add("b_id",b.getUserId().toString());
        data.add("b_bot_id",b.getBotId().toString());
        restTemplate.postForObject(startGameUrl,data,String.class);
    }
    @Override
    public void run(){
        while(true){
            try{
                Thread.sleep(1000); //每隔一秒钟
                //increaseWaitingTime 和 matchPlayers 都会操纵players
                //可能会产生读写冲突 因此加锁
                lock.lock();
                try{
                    increaseWaitingTime();
                    matchPlayers();
                }finally {
                    lock.unlock();
                }

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

}
